package com.jsoft.jsofted.framework.utils;

import com.diboot.core.util.D;
import com.diboot.core.util.PropertiesUtils;
import com.diboot.file.config.Cons;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;

/**
 * 文件助手：提供上传文件、数据（模板）文件、导出(Excel数据)文件的常用方法。
 */
@Slf4j
public class FileHelper {
    public static final String POINT = ".";
    public static final String HTTP = "http";
    public static final String QUESTION_MARK = "?";
    /**
     * 危险文件后缀清单
     */
    public static final List<String> DANGER_FILE_SUFFIX = Arrays.asList("exe", "bat", "bin", "dll", "sh");
    /**
     * 上传文件存储路径
     */
    public static final String UPLOAD_DIRECTORY = "jsofted.directory.upload";
    /**
     * 数据(模板)文件存储路径
     */
    public static final String DATA_DIRECTORY = "jsofted.directory.data";
    /**
     * 导出(Excel、PDF等报表)文件存储路径
     */
    public static final String EXPORT_DIRECTORY = "jsofted.directory.export";
    /**
     * Excel文件后缀清单
     */
    private static final List<String> EXCEL_SUFFIX = Arrays.asList("xls", "xlsx", "xlsm");
    /**
     * 图片文件后缀清单
     */
    private static final List<String> IMAGE_SUFFIX = Arrays.asList("jpg", "jpeg", "png", "gif", "bmp", "tif");

    private static String uploadDirectory = null;
    private static String dataDirectory = null;
    private static String exportDirectory = null;

    public static boolean isValidFile(String fileName) {
        String ext = FileHelper.getFileExtByName(fileName);
        return !DANGER_FILE_SUFFIX.contains(ext.toLowerCase());
    }

    public static boolean isExcel(String fileName) {
        String ext = FileHelper.getFileExtByName(fileName);
        return EXCEL_SUFFIX.contains(ext.toLowerCase());
    }

    public static boolean isImage(String fileName) {
        String ext = FileHelper.getFileExtByName(fileName);
        return IMAGE_SUFFIX.contains(ext.toLowerCase());
    }

    public static String saveUploadFile(MultipartFile file, String fileName) {
        // 生成文件路径
        String fullPath = getUploadFileFullPath(fileName);
        try {
            // 创建文件夹
            makeDirectory(fullPath);
            FileUtils.writeByteArrayToFile(new File(fullPath), file.getBytes());
            if (log.isDebugEnabled()) {
                log.debug("保存文件成功！路径为: " + fullPath);
            }
            return fullPath;
        } catch (IOException e1) {
            log.error("保存文件失败(file=" + fullPath + "): ", e1);
            return null;
        }
    }

    public static String getFileExtByName(String fileName) {
        if (fileName.startsWith(HTTP) && fileName.contains(Cons.FILE_PATH_SEPARATOR)) {
            fileName = getFileName(fileName);
        }
        if (fileName.lastIndexOf(POINT) > 0) {
            return fileName.substring(fileName.lastIndexOf(POINT) + 1).toLowerCase();
        }
        log.warn("检测到没有后缀的文件名:" + fileName);
        return "";
    }

    public static String getFileRelativePath(String fileName) {
        StringBuilder sb = new StringBuilder();
        String tenantId = null;// LoginHolder.getTenantId();
        if (tenantId == null) {
            tenantId = "0";
        }
        sb.append("/").append(tenantId).append("/").append(D.getYearMonth()).append("/").append(fileName);
        return sb.toString();
    }

    public static String getUploadFileFullPath(String fileName) {
        String relativePath = getFileRelativePath(fileName);
        return getUploadDirectory() + relativePath;
    }

    public static String getUploadDirectory() {
        if (uploadDirectory == null) {
            uploadDirectory = PropertiesUtils.get(UPLOAD_DIRECTORY);
            if (uploadDirectory == null) {
                throw new CocException("上传文件存储路径参数 " + UPLOAD_DIRECTORY + " 未配置.");
            }
        }
        return uploadDirectory;
    }

    public static String getDataFileFullPath(String fileName) {
        String relativePath = getFileRelativePath(fileName);
        return getDataDirectory() + relativePath;
    }

    public static String getDataDirectory() {
        if (dataDirectory == null) {
            dataDirectory = PropertiesUtils.get(DATA_DIRECTORY);
            if (dataDirectory == null) {
                throw new CocException("数据文件存储路径参数 " + DATA_DIRECTORY + " 未配置.");
            }
        }
        return dataDirectory;
    }

    public static String getExportFileFullPath(String fileName) {
        String relativePath = getFileRelativePath(fileName);
        return getExportDirectory() + relativePath;
    }

    public static String getExportDirectory() {
        if (exportDirectory == null) {
            exportDirectory = PropertiesUtils.get(EXPORT_DIRECTORY);
            if (exportDirectory == null) {
                throw new CocException("导出文件存储路径参数 " + EXPORT_DIRECTORY + " 未配置.");
            }
        }
        return exportDirectory;
    }

    public static boolean makeDirectory(String dirPath) {
        String directory = StringUtils.substringBeforeLast(dirPath, Cons.FILE_PATH_SEPARATOR);
        File dir = new File(directory);
        if (!dir.exists()) {
            try {
                FileUtils.forceMkdir(dir);
                return true;
            } catch (IOException e) {
                log.error("创建文件夹失败", e);
                return false;
            }
        }
        return false;
    }


    public static String getFileName(String fileUrl) {
        String temp = StringUtils.substring(fileUrl, fileUrl.lastIndexOf(Cons.FILE_PATH_SEPARATOR) + 1);
        if (StringUtils.contains(fileUrl, QUESTION_MARK)) {
            temp = StringUtils.substring(temp, 0, temp.lastIndexOf(QUESTION_MARK));
        }
        return temp;
    }

    public static boolean deleteFile(String fileStoragePath) {
        File file = new File(fileStoragePath);
        if (file.exists()) {
            return file.delete();
        }
        return false;
    }

}